package ca.cbc.msb.mq;

import javax.jms.JMSException;
import javax.naming.NamingException;

import ca.cbc.msb.util.FTPUtil;
import ca.cbc.msb.util.ProgressReport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ca.cbc.medialib.entity.Media;
import ca.cbc.medialib.entity.enums.ProcessStatus;
import ca.cbc.medialib.util.ApplicationContextUtil;
import ca.cbc.msb.entity.MSBMessage;
import ca.cbc.msb.enums.QueueEnum;
import ca.cbc.msb.gsa.GSAService;
import ca.cbc.msb.mobilemedia.MobileMediaService;
import ca.cbc.msb.mobilemedia.YospaceServiceImpl;
import ca.cbc.msb.persistence.FailedMediaPersistence;
import ca.cbc.msb.persistence.MediaPersistence;
import ca.cbc.msb.persistence.ProcessingStatusPersistence;

/**
 * JMS implementation of MessageHandler for performing business logic for change media message.
 *
 * @author william wei
 */
public class ChangedMediaMessageHandler implements MessageHandler {

	private Logger log = LoggerFactory.getLogger(this.getClass());
    private GSAService gsaService;
    private MediaPersistence mediaPersistence;
    private FailedMediaPersistence failedMediaPersistence;
    private ProcessingStatusPersistence processingStatusPersistence;
    private MobileMediaService mobileMediaService;

    public ChangedMediaMessageHandler() {
    	gsaService = new GSAService();
    	mobileMediaService = new YospaceServiceImpl();
    	mediaPersistence = ApplicationContextUtil.instance.getApplicationContext().getBean(MediaPersistence.class);
    	failedMediaPersistence = ApplicationContextUtil.instance.getApplicationContext().getBean(FailedMediaPersistence.class);
    	processingStatusPersistence = ApplicationContextUtil.instance.getApplicationContext().getBean(ProcessingStatusPersistence.class);  	
    }
    
    /**
     * @param message     MSBMessage, containing   release information
     * @param messageUtil MessageUtil, maintain jms connection and a series of message queues. send /receive message to/form message queues.
     */
    @Override
    public void handle(MSBMessage message, MessageUtil messageUtil) throws NamingException, JMSException {
        log.debug(">>>ChangedMediaMessage Received ({})", message);
        Media media = message.getMedia();
        boolean isSumbitToYospace = false;
        
        try {
        	//0. commit received message
        	messageUtil.commit();

        	//1. sumbit to GSA
	        gsaService.submitToGSA(message);
	        
	        //2. yospace?
	        if(media.getAvailableInMobile().equalsIgnoreCase("true")) {
	        	Media mediaDB = mediaPersistence.findById(media.getReleaseId());
	        	if ((mediaDB == null || mediaDB.getMobileId() == 0) && FTPUtil.isFile(media.getOriginalFileName())) {
	                //Media doesn't have a Yospace ID, submit to Yospace
	        		processingStatusPersistence.changeProcessingFlag(message, ProcessStatus.UPLOAD_TO_MOBILE);
	        		mobileMediaService.addMedia(message);
	        		messageUtil.submitMessage(QueueEnum.YospaceVerificationQueue, message);
	        		messageUtil.commit(); //commit for submit message
	                isSumbitToYospace = true;
	                ProgressReport.instance.statusReport(message, "Submitted to Yospace, Waiting For verification");
	                log.info("ChangedMediaMessage({}) submit to yospace.", message);
	        	} else if(mediaDB != null && mediaDB.getMobileId() != 0) { //media is in DB and Yospace, just update the Yospace
	                ProgressReport.instance.statusReport(message, "Successfully updated in database");
	                ProgressReport.instance.statusReport(message, "Already In Yospace, Processing Finished Successfully.");
	                mobileMediaService.changeMedia(message);
	        		log.info("Media({}) with yospace Id already in DB, just update yospace.", message);
	        	} else {
	        		log.info("Media({}) is not in ftp and not have yospace Id, must be MRB, do nothing.", message);
	        	}
	        } else {
	        	log.info("ChangedMediaMessage ({}) AvailableInMobile is false, no changes to Yospace needed, save to DB>>>", message);
	        }
	        	
	        //3. save or update to db
	        if(!isSumbitToYospace) {
	        	mediaPersistence.saveOrMerge(media);
	        }
        } catch (Exception e) {
        	failedMediaPersistence.save(media);
        	log.error("Unkonw error when processing changed media, abort further action.", e);
        } finally { //will remove processing flag as long as not submit to yospace
        	if(!isSumbitToYospace) {
        		processingStatusPersistence.removeProcessingFlag(message);
        	}
        }
    }

//    private void saveMetaDataChanges(MSBMessage message, Media mediaDB) {
//        Media media =message.getMedia() ;
//        if (!strEqual(mediaDB.getTitle(), media.getTitle()) ||
//                !strEqual(mediaDB.getDescription(), media.getDescription()) ||
//                !strEqual(mediaDB.getCountries(), media.getCountries()) ||
//                mediaDB.getExcludeCountries() != mediaDB.getExcludeCountries() ||
//                !strEqual(mediaDB.getAccount(), media.getAccount()) ||
//                !strEqual(mediaDB.getShow(), media.getShow()) ||
//                !strEqual(mediaDB.getEpisodeNumber(), media.getEpisodeNumber()) ||
//                !strEqual(mediaDB.getSeasonNumber(), media.getSeasonNumber())) {
//            mobileMediaService.changeMedia(message);
//            log.info("ChangedMediaMessage ({}) changed to the yospace...", message);
//            ProcessingStatusPersistance.instance.removeProcessingFlagWithoutTransaction(message);
//            log.info("^-^-^-^Removing process flag for message({})...", message);
//            ProgressReport.instance.statusReport(message, "Media was already in Yospace. Metadata changed in msb successfully.");
//        } else {
//            log.info("ChangedMediaMessage ({}) no need for changing to the yospace...", message);
//        }
//        //merge for changes
//        mediaStorageService.mergeMedia(media);
//        log.info("ChangedMediaMessage ({}) AvailableInMobile is true, merge to DB>>>", message);
//    }
}
